/****************************************************************************
 * Dirve lcd19264 , mode 8080. Tested on ABG192064C00-v1.0
 * Tested MCU pic18f24k22
 * Owner : apleilx
 * 
 * Frequence : 12MHz
 * 
 * Some samble :
 * CN------------Chianese
 * Page----------The Page of LCD
 * Col-----------The col address of LCD
 * 16_16_________A char that is 16*16 dots
 * U-------------The chip select for LCD,(CS1--left / CS2--middle / CS3--right)
 * Com-----------LCD command
 * Disp----------Display
 * W-------------write
 * Rec-----------recently
 * Img-----------Image
 * Anti----------Anti-color
 * DIR-----------direction
 * DEL-----------delay
 * Explanation:
 * ANSEL must be set again
 * This file relay on ASCII_16_32.c,ASCII_8_16,and a function _FlashReadBytes
 * that is in pic18f2xk22flash.h .
 * If you replace MCU ,you must surport a fuctions that names _FlashReadBytes  to read flash.
 * ASCII_16_32.c and ASCII_8_16 is unrelaied on hardware ,you can copy those to your project.
 * Imag.c and CN_16_16_Index.c is not necessary ,unless you want to display chianese and image.
 * ASCII_16_32.c surport the address of the virious ,you can change it with your MCU.
 * **************************************************************************/


#include "ascii.h"
#include "system.h"
#include "pic18_flash.h"
/**************************************************************************
 * define control bit for LCD19264
 *************************************************************************/
#define LCD19264_CS1       LATAbits.LA0
#define LCD19264_CS1_DIR   TRISAbits.TRISA0
#define LCD19264_CS2       LATBbits.LB5
#define LCD19264_CS2_DIR   TRISBbits.TRISB5
#define LCD19264_CS3       LATBbits.LB4
#define LCD19264_CS3_DIR   TRISBbits.TRISB4
#define LCD19264_E         LATAbits.LA2
#define LCD19264_E_DIR     TRISAbits.TRISA2
#define LCD19264_RW        LATBbits.LB1
#define LCD19264_RW_DIR    TRISBbits.TRISB1
#define LCD19264_RS        LATAbits.LA3
#define LCD19264_RS_DIR    TRISAbits.TRISA3
#define LCD19264_BUSY      PORTDbits.RD7
#define LCD19264_BUSY_DIR  TRISDbits.TRISD7
#define LCD19264_RESET     LATAbits.LA1
#define LCD19264_RESET_DIR TRISAbits.TRISA1
#define LCD19264_DATA      PORTD
#define LCD19264_DATA_DIR  TRISD

/*****************************************************************************
 *lcd E delay , 450ns
 ****************************************************************************/
#define LCD19264_E_DEL     {\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
}
#define LCD19264_Com_DEL {\
asm("nop");\
asm("nop");\
asm("nop");\
}

#define LCD19264_Sub_DEL{\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
}
/*****************************************************************************
 *lcd Ready delay , 350ns 
 ****************************************************************************/
#define LCD19264_Read_DEL     {\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
}

#define LCD19264_RESET_DEL   {\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
asm("nop");\
}

typedef union{
    unsigned char Full;
    struct{
        unsigned     bit0 :1;
        unsigned     bit1 :1;
        unsigned     bit2 :1;
        unsigned     bit3 :1;
        unsigned     bit4 :1;
        unsigned     bit5 :1;
        unsigned     bit6 :1;
        unsigned     bit7 :1;
    };
} CharBitsTyp;

unsigned char LCD19264_DispBuffer[64];

/******************************************************************************
 * Waiting LCD untile it is not busy
 * @param Content
 *****************************************************************************/
void LCD19264_Busy()
{
    LCD19264_DATA_DIR = 0x0ff;
    LCD19264_RS = 0;
    LCD19264_RW = 1;
    LCD19264_Com_DEL;
    LCD19264_E  = 1;
    LCD19264_Read_DEL;
    while(LCD19264_BUSY);
    LCD19264_E = 0;
}

/******************************************************************************
 * Invert the bits of the received data, and return the result.
 * @param Content
 *****************************************************************************/
unsigned char BitInvert(unsigned char Data)
{
    CharBitsTyp Temp,Result;
    Temp.Full = Data;
    Result.bit0 = Temp.bit7;
    Result.bit1 = Temp.bit6;
    Result.bit2 = Temp.bit5;
    Result.bit3 = Temp.bit4;
    Result.bit4 = Temp.bit3;
    Result.bit5 = Temp.bit2;
    Result.bit6 = Temp.bit1;
    Result.bit7 = Temp.bit0;
    return Result.Full;
}

/******************************************************************************
 * Write data to CS1
 * @param Content
 *****************************************************************************//*
void LCD19264_WriteData_CS1(unsigned char Content)
{
    LCD19264_CS1=0;
    LCD19264_CS2=1;
    LCD19264_CS3=1;
    LCD19264_Busy();
    LCD19264_RS = 1;        //data
    LCD19264_RW = 0;        //write
    LCD19264_DATA_DIR = 0;
    LCD19264_DATA     = Content;
    LCD19264_Com_DEL;
    LCD19264_E        = 1;
    LCD19264_E_DEL;
    LCD19264_E = 0;
}*/
/******************************************************************************
 * Write data to CS2
 * @param Content
 *****************************************************************************//*
void LCD19264_WriteData_CS2(unsigned char Content)
{
    LCD19264_CS1=1;
    LCD19264_CS2=0;
    LCD19264_CS3=1;
    LCD19264_Busy();
    LCD19264_RS = 1;        //data
    LCD19264_RW = 0;        //write
    LCD19264_DATA_DIR = 0;
    LCD19264_DATA     = Content;
    LCD19264_Com_DEL;
    LCD19264_E        = 1;
    LCD19264_E_DEL;
    LCD19264_E = 0;
}*/
/******************************************************************************
 * Write data to CS3
 * @param Content
 *****************************************************************************//*
void LCD19264_WriteData_CS3(unsigned char Content)
{
    LCD19264_CS1=1;
    LCD19264_CS2=1;
    LCD19264_CS3=0;
    LCD19264_Busy();
    LCD19264_RS = 1;        //data
    LCD19264_RW = 0;        //write
    LCD19264_DATA_DIR = 0;
    LCD19264_DATA     = Content;
    LCD19264_Com_DEL;
    LCD19264_E        = 1;
    LCD19264_E_DEL;
    LCD19264_E = 0;
}*/
/******************************************************************************
 * Write data to CS1/CS2/CS3
 * @param Content
 *****************************************************************************//*
void LCD19264_WriteData(unsigned char U,unsigned char Content)
{
    if(U == 1)
    {
        LCD19264_CS1=0;
        LCD19264_CS2=1;
        LCD19264_CS3=1;
    }
    else if(U == 2)
    {
        LCD19264_CS1=1;
        LCD19264_CS2=0;
        LCD19264_CS3=1;
    }
    else
    {
        LCD19264_CS1=1;
        LCD19264_CS2=1;
        LCD19264_CS3=0;
    }
    LCD19264_Busy();
    LCD19264_RS = 1;        //data
    LCD19264_RW = 0;        //write
    LCD19264_DATA_DIR = 0;
    LCD19264_DATA     = Content;
    LCD19264_Com_DEL;
    LCD19264_E        = 1;
    LCD19264_E_DEL;
    LCD19264_E = 0;
}*/
/******************************************************************************
 * Read data from CS1
 * @param Content
 *****************************************************************************//*
unsigned char LCD19264_ReadData_CS1()
{
    unsigned char ReadTemp;
    LCD19264_CS1=0;
    LCD19264_CS2=1;
    LCD19264_CS3=1;
    
    LCD19264_Busy();
    LCD19264_RS = 1;           //data
    LCD19264_RW = 1;           //write
    LCD19264_DATA_DIR = 0x0ff;
    LCD19264_Com_DEL;
    LCD19264_E        = 1;
    LCD19264_E_DEL;
    ReadTemp = LCD19264_DATA;
    LCD19264_E = 0;
    return ReadTemp;
}
unsigned char LCD19264_ReadData_CS2()
{
    unsigned char ReadTemp;
    LCD19264_CS1=1;
    LCD19264_CS2=0;
    LCD19264_CS3=1;

    LCD19264_Busy();
    LCD19264_RS = 1;           //data
    LCD19264_RW = 1;           //write
    LCD19264_DATA_DIR = 0x0ff;
    LCD19264_Com_DEL;
    LCD19264_E        = 1;
    LCD19264_E_DEL;
    ReadTemp = LCD19264_DATA;
    LCD19264_E = 0;
    return ReadTemp;
}
unsigned char LCD19264_ReadData_CS3()
{
    unsigned char ReadTemp;
    LCD19264_CS1=1;
    LCD19264_CS2=1;
    LCD19264_CS3=0;

    LCD19264_Busy();
    LCD19264_RS = 1;           //data
    LCD19264_RW = 1;           //write
    LCD19264_DATA_DIR = 0x0ff;
    LCD19264_Com_DEL;
    LCD19264_E        = 1;
    LCD19264_E_DEL;
    ReadTemp = LCD19264_DATA;
    LCD19264_E = 0;
    return ReadTemp;
}
*/
/******************************************************************************
 * Write command to CS1
 * @param Content
 *****************************************************************************/
void LCD19264_WriteCom_CS1(unsigned char Content)
{
    LCD19264_CS1=0;
    LCD19264_CS2=1;
    LCD19264_CS3=1;

    LCD19264_Busy();
    LCD19264_RS = 0;         //com
    LCD19264_RW = 0;         //write
    LCD19264_DATA_DIR = 0;
    LCD19264_DATA     = Content;
    LCD19264_Com_DEL;
    LCD19264_E        = 1;
    LCD19264_E_DEL;
    LCD19264_E = 0;
}
/******************************************************************************
 * Write command to CS2
 * @param Content
 *****************************************************************************/
void LCD19264_WriteCom_CS2(unsigned char Content)
{
    LCD19264_CS1=1;
    LCD19264_CS2=0;
    LCD19264_CS3=1;

    LCD19264_Busy();
    LCD19264_RS = 0;         //com
    LCD19264_RW = 0;        //write
    LCD19264_DATA_DIR = 0;
    LCD19264_DATA     = Content;
    LCD19264_Com_DEL;
    LCD19264_E        = 1;
    LCD19264_E_DEL;
    LCD19264_E = 0;
}
/******************************************************************************
 * Write command to CS3
 * @param Content
 *****************************************************************************/
void LCD19264_WriteCom_CS3(unsigned char Content)
{

    LCD19264_CS1=1;
    LCD19264_CS2=1;
    LCD19264_CS3=0;

    LCD19264_Busy();
    LCD19264_RS = 0;         //com
    LCD19264_RW = 0;         //write
    LCD19264_DATA_DIR = 0;
    LCD19264_DATA     = Content;
    LCD19264_Com_DEL;
    LCD19264_E        = 1;
    LCD19264_E_DEL;
    LCD19264_E = 0;
}
/******************************************************************************
 * Write command to CS1/CS2/CS3
 * @param Content
 *****************************************************************************/
void LCD19264_WriteCom(unsigned char U,unsigned char Content)
{
    if(U == 1)
    {
        LCD19264_CS1=0;
        LCD19264_CS2=1;
        LCD19264_CS3=1;
    }
    else if(U == 2)
    {
        LCD19264_CS1=1;
        LCD19264_CS3=1;
        LCD19264_CS2=0;
    }
    else
    {
        LCD19264_CS1=1;
        LCD19264_CS2=1;
        LCD19264_CS3=0;
    }
    LCD19264_Busy();
    LCD19264_RS = 0;         //com
    LCD19264_RW = 0;        //write
    LCD19264_DATA_DIR = 0;
    LCD19264_DATA     = Content;
    LCD19264_Com_DEL;
    LCD19264_E        = 1;
    LCD19264_E_DEL;
    LCD19264_E = 0;
}
/**************************************************************************
 *Write data or command to CS1
 *************************************************************************//*
void LCD19264_Write_CS1(unsigned char Com_Data,unsigned char Content)
{
    LCD19264_CS1=0;
    LCD19264_CS2=1;
    LCD19264_CS3=1;
    LCD19264_Busy();
    if(Com_Data == 0)
    {
         LCD19264_RS = 0;   //com
    }
    else
    {
         LCD19264_RS = 1;   //data
    }
    LCD19264_RW = 0;        //write
    LCD19264_DATA_DIR = 0;
    LCD19264_DATA     = Content;
    LCD19264_Com_DEL;
    LCD19264_E        = 1;
    LCD19264_E_DEL;
    LCD19264_E = 0;
}*/
/**************************************************************************
 *Write data or command to CS2
 *************************************************************************//*
void LCD19264_Write_CS2(unsigned char Com_Data,unsigned char Content)
{
    LCD19264_CS1=1;
    LCD19264_CS2=0;
    LCD19264_CS3=1;
    LCD19264_Busy();
    if(Com_Data == 0)
    {
         LCD19264_RS = 0;   //com
    }
    else
    {
         LCD19264_RS = 1;   //data
    }
    LCD19264_RW = 0;        //write
    LCD19264_DATA_DIR = 0;
    LCD19264_DATA     = Content;
    LCD19264_Com_DEL;
    LCD19264_E        = 1;
    LCD19264_E_DEL;
    LCD19264_E = 0;
}*/
/**************************************************************************
 *Write data or command to CS3
 *************************************************************************//*
void LCD19264_Write_CS3(unsigned char Com_Data,unsigned char Content)
{
    LCD19264_CS1=1;
    LCD19264_CS2=1;
    LCD19264_CS3=0;
    LCD19264_Busy();
    if(Com_Data == 0)
    {
         LCD19264_RS = 0;   //com
    }
    else
    {
         LCD19264_RS = 1;   //data
    }
    LCD19264_RW = 0;        //write
    LCD19264_DATA_DIR = 0;
    LCD19264_DATA     = Content;
    LCD19264_Com_DEL;
    LCD19264_E        = 1;
    LCD19264_E_DEL;
    LCD19264_E = 0;
}*/
/******************************************************************************
 * Write command or data to CS1/CS2/CS3
 * @param Content
 *****************************************************************************//*
void LCD19264_Write(unsigned char U,unsigned char Com_Data,unsigned char Content)
{
    if(U == 1)
    {
        LCD19264_CS1=0;
        LCD19264_CS2=1;
        LCD19264_CS3=1;
    }
    else if(U == 2)
    {
        LCD19264_CS1=1;
        LCD19264_CS2=0;
        LCD19264_CS3=1;
    }
    else
    {
        LCD19264_CS1=1;
        LCD19264_CS2=1;
        LCD19264_CS3=0;
    }
    LCD19264_Busy();
    if(Com_Data == 0)
    {
         LCD19264_RS = 0;   //com
    }
    else
    {
         LCD19264_RS = 1;   //data
    }
    LCD19264_RW = 0;        //write
    LCD19264_DATA_DIR = 0;
    LCD19264_DATA     = Content;
    LCD19264_Com_DEL;
    LCD19264_E        = 1;
    LCD19264_E_DEL;
    LCD19264_E = 0;
}
*/
void LCD19264_ComW(unsigned char Command)
{
    LCD19264_Busy();
    LCD19264_RS = 0;         //com
    LCD19264_RW = 0;        //write
    LCD19264_DATA_DIR = 0;
    LCD19264_DATA     = Command;
    LCD19264_Com_DEL;
    LCD19264_E        = 1;
    LCD19264_E_DEL;
    LCD19264_E = 0;
}

void LCD19264_DataW(unsigned char Data)
{
    LCD19264_Busy();
    LCD19264_RS = 1;        //data
    LCD19264_RW = 0;        //write
    LCD19264_DATA_DIR = 0;
    LCD19264_DATA     = Data;
    LCD19264_Com_DEL;
    LCD19264_E        = 1;
    LCD19264_E_DEL;
    LCD19264_E = 0;
}
/*
void LCD19264_PageSet(unsigned char U,unsigned char Page)
{
    LCD19264_WriteCom(U,(0xB8 + Page));
}
void LCD19264_ColSet(unsigned char U,unsigned char Col)
{
    LCD19264_WriteCom(U,(0x40 + Col));
}
*/
/******************************************************************************
 * Clear the screen
 * @param Content
 *****************************************************************************/
void LCD19264_ScreenClr()
{
    unsigned char Col,Page;
    Page = 0;
    for(Page=0;Page<8;Page++)
    {
        LCD19264_WriteCom_CS1(0xB8+Page);
        LCD19264_WriteCom_CS1(0x40);
        for(Col=0;Col<64;Col++)
        {
            LCD19264_Sub_DEL;
            LCD19264_DataW(0);
         }
    }
    for(Page=0;Page<8;Page++)
    {
        LCD19264_WriteCom_CS2(0xB8+Page);
        LCD19264_WriteCom_CS2(0x40);
        for(Col=0;Col<64;Col++)
        {
            LCD19264_Sub_DEL;
            LCD19264_DataW(0);
         }
    }
    for(Page=0;Page<8;Page++)
    {
        LCD19264_WriteCom_CS3(0xB8+Page);
        LCD19264_WriteCom_CS3(0x40);
        for(Col=0;Col<64;Col++)
        {
            LCD19264_Sub_DEL;
            LCD19264_DataW(0);
        }
    }
    asm("nop");
}

/******************************************************************************
 * Display a chianese on the left screen
 * @param Content
 *****************************************************************************/

/******************************************************************************
 * Set start line on screen
 * @param Content
 *****************************************************************************/
void LCD19264_StartLine_All(unsigned char Line)
{
    LCD19264_WriteCom_CS1( 0xC0 + Line);
    LCD19264_WriteCom_CS2( 0xC0 + Line);
    LCD19264_WriteCom_CS3( 0xC0 + Line);
}
/******************************************************************************
 * Set start line on screen
 * @param Content
 *****************************************************************************/
void LCD19264_StartLine_CS1(unsigned char Line)
{
    LCD19264_WriteCom_CS1( 0xC0 + Line);
}
/******************************************************************************
 * Set start line on screen
 * @param Content
 *****************************************************************************/
void LCD19264_StartLine_CS2(unsigned char Line)
{
    LCD19264_WriteCom_CS2( 0xC0 + Line);
}
/******************************************************************************
 * Set start line on screen
 * @param Content
 *****************************************************************************/
void LCD19264_StartLine_CS3(unsigned char Line)
{
    LCD19264_WriteCom_CS3( 0xC0 + Line);
}

/******************************************************************************
 * Set start line on screen
 * @param Content
 *****************************************************************************/
void LCD19264_StartLine(unsigned char U,unsigned char Line)
{
    switch(U)
    {
        case 1:
        LCD19264_WriteCom_CS1( 0xC0 + Line);
        return;
        case 2:
        LCD19264_WriteCom_CS2( 0xC0 + Line);
        return;
        case 3:
        LCD19264_WriteCom_CS3( 0xC0 + Line);
        return;
        default:return;
    }
}
/******************************************************************************
 * Init
 * @param Content
 *****************************************************************************/
void LCD19264_Init()
{
 LCD19264_CS1_DIR = 0;
 LCD19264_CS2_DIR = 0;
 LCD19264_CS3_DIR = 0;
 LCD19264_CS1     = 1;
 LCD19264_CS2     = 1;
 LCD19264_CS3     = 1;

 LCD19264_E_DIR   = 0;
 LCD19264_E       = 0;

 LCD19264_RW_DIR  = 0;
 LCD19264_RW      = 0;
 LCD19264_RS_DIR  = 0;
 LCD19264_RS      = 0;

 LCD19264_DATA_DIR =0x0FF;

 LCD19264_RESET_DIR = 0;
 LCD19264_RESET     = 0;
 LCD19264_RESET_DEL ;
 LCD19264_RESET     = 1;
 LCD19264_RESET_DEL ;
 LCD19264_RESET     = 0;
 LCD19264_RESET_DEL ;
 LCD19264_RESET     = 1;


 LCD19264_WriteCom_CS1(0x3E);
 LCD19264_WriteCom_CS2(0x3E);
 LCD19264_WriteCom_CS3(0x3E);

 LCD19264_WriteCom_CS1(0x3F);
 LCD19264_WriteCom_CS2(0x3F);
 LCD19264_WriteCom_CS3(0x3F);

 LCD19264_WriteCom_CS1(0xc0);
 LCD19264_WriteCom_CS2(0xc0);
 LCD19264_WriteCom_CS3(0xc0);
 
 LCD19264_ScreenClr();


}

void LCD19264_CharDisp(unsigned char Page,unsigned char Col,unsigned char DispCh)
{
    unsigned char LMR;              // left /middle /right screen
    unsigned char ColCounter;
    ColCounter = 0;
    if(Page >= 7) return;
    if(Col > 184) return;
    LMR = 1;
    while(Col >= 64)
    {
        Col -= 64;
        LMR ++;
    }
    if(Col > 56) return;
    for(unsigned char i=0;i<16;i++)               //Read the img of DispCh
    {
       LCD19264_DispBuffer[i] = ASCII_SongTi_8_16[DispCh-32][i];
    }
    LCD19264_WriteCom(LMR,0xB8 + Page);           // Set the first Page of the char
    LCD19264_WriteCom(LMR,0x40 + Col);            // Set the start Col of the char
    while(ColCounter < 8)                         //Write the first page of the char
    {
       LCD19264_DataW( LCD19264_DispBuffer[ColCounter ++] );
    }
    LCD19264_WriteCom(LMR,0xB8 + Page + 1);       // Set the second Page of the char
    LCD19264_WriteCom(LMR,0x40 + Col);            // Set start Col of the char
    while(ColCounter < 16)                        //Write the first page of the char
    {
        LCD19264_DataW( LCD19264_DispBuffer[ColCounter ++] );
    }
}

void LCD19264_CharDisp_Anti(unsigned char Page,unsigned char Col,unsigned char DispCh)
{
    unsigned char LMR;              // left /middle /right screen
    unsigned char ColCounter;
    ColCounter = 0;
    if(Page >= 7) return;
    if(Col > 184) return;
    LMR = 1;
    while(Col >= 64)
    {
        Col -= 64;
        LMR ++;
    }
    if(Col > 56) return;
    for(unsigned char i=0;i<16;i++)               //Read the img of DispCh
    {
       LCD19264_DispBuffer[i] = ASCII_SongTi_8_16[DispCh-32][i];
    }
    LCD19264_WriteCom(LMR,0xB8 + Page);           // Set the first Page of the char
    LCD19264_WriteCom(LMR,0x40 + Col);            // Set the start Col of the char
    while(ColCounter < 8)                         //Write the first page of the char
    {
       LCD19264_DataW( ~LCD19264_DispBuffer[ColCounter ++] );
    }
    LCD19264_WriteCom(LMR,0xB8 + Page + 1);       // Set the second Page of the char
    LCD19264_WriteCom(LMR,0x40 + Col);            // Set start Col of the char
    while(ColCounter < 16)                        //Write the first page of the char
    {
        LCD19264_DataW( ~LCD19264_DispBuffer[ColCounter ++] );
    }
}
/******************************************************************************
 * This function only can display ASCII character , if you send a character
 * that is not between ' 'and '~'in ASCII ,the function will be stop and out;
 *
 * The Page must between 0 and 4
 * The Col must between 0 and 191,and is a multiple of 16.
 * @param Content
 *****************************************************************************/
void LCD19264_Char16_32Disp(unsigned char Page,unsigned char Col,unsigned char DispCh)
{
    unsigned char LMR;              // left /middle /right screen
    unsigned char ColCounter;
    unsigned char Index;
    ColCounter = 0;
    Index = 0;
    if(Page > 4) return;
    if(Col > 176) return;
    LMR = 1;
    while(Col >= 64)
    {
        Col -= 64;
        LMR ++;
    }
    if(Col > 48) return;
    _FlashReadBytes(ASCII_SONGTI_16_32BASE + ((unsigned long)(DispCh)-32)*64 ,64,LCD19264_DispBuffer );
    for(unsigned char j=0;j<4;j++)
    {
        ColCounter = 0;
        LCD19264_WriteCom(LMR,0xB8 + Page +j);           // Set the first Page of the char
        LCD19264_WriteCom(LMR,0x40 + Col);            // Set the start Col of the char
        while(ColCounter < 16)                         //Write the first page of the char
        {
        LCD19264_DataW( LCD19264_DispBuffer[Index ++] );
        ColCounter ++;
        }
    }
}

void LCD19264_Char16_32Disp_Anti(unsigned char Page,unsigned char Col,unsigned char DispCh)
{
    unsigned char LMR;              // left /middle /right screen
    unsigned char ColCounter;
    unsigned char Index;
    ColCounter = 0;
    Index = 0;
    if(Page > 4) return;
    if(Col > 176) return;
    LMR = 1;
    while(Col >= 64)
    {
        Col -= 64;
        LMR ++;
    }
    if(Col > 48) return;
    _FlashReadBytes(ASCII_SONGTI_16_32BASE + ((unsigned long)(DispCh)-32)*64 ,64,LCD19264_DispBuffer );
    for(unsigned char j=0;j<4;j++)
    {
        ColCounter = 0;
        LCD19264_WriteCom(LMR,0xB8 + Page +j);           // Set the first Page of the char
        LCD19264_WriteCom(LMR,0x40 + Col);            // Set the start Col of the char
        while(ColCounter < 16)                         //Write the first page of the char
        {
        LCD19264_DataW( ~LCD19264_DispBuffer[Index ++] );
        ColCounter ++;
        }
    }
}

/******************************************************************************
 * This function used to display a string ,the string must be end of '\n'.
 * If it is not end of '\n' ,you may be see something unknown on your lcd.
 * This function only can display ASCII character , if you send a character
 * that is not between ' 'and '~'in ASCII ,the function will be stop and out;
 *
 * The Page must between 0 and 6
 * The Col must between 0 and 191,and is a multiple of 8.
 *
 * Fnally,this is just a simple function that does not support formatted output.
 * @param Content
 *****************************************************************************/
void LCD19264_StringDisp(unsigned char Page,unsigned char Col,unsigned char *DispStr)
{
    unsigned char LMR;              // left /middle /right screen
    unsigned char DispCh = 0;
    unsigned char ColCounter;
    unsigned char ColTest;
    ColTest = Col;
    if(Page >= 8) return;
    if(Col >= 192) return;
    while(ColTest >= 8)
    {
        ColTest -= 8;
    }
    if(ColTest != 0) return;

    LMR = 1;
    while(Col >= 64)
    {
        Col -= 64;
        LMR ++;
    }

    ColCounter = 0;
    while(LMR < 4)
    {
        while(Col <= 56)
        {
            LCD19264_WriteCom(LMR,0xB8 + Page);           // Set the first Page of the char
            LCD19264_WriteCom(LMR,0x40 + Col);            // Set the start Col of the char

            DispCh = *(DispStr ++);                       //Read a char to display
            if( (DispCh >126) || (DispCh <32) ) return;   //test the char leagle or not

            for(unsigned char i=0;i<16;i++)               //Read the img of DispCh
            {
                LCD19264_DispBuffer[i] = ASCII_SongTi_8_16[DispCh-32][i];
            }

            while(ColCounter < 8)                         //Write the first page of the char
            {
                LCD19264_DataW( LCD19264_DispBuffer[ColCounter ++] );
            }
            LCD19264_WriteCom(LMR,0xB8 + Page + 1);       // Set the second Page of the char
            LCD19264_WriteCom(LMR,0x40 + Col);            // Set start Col of the char
            while(ColCounter < 16)                        //Write the first page of the char
            {
                LCD19264_DataW( LCD19264_DispBuffer[ColCounter ++] );
            }
            Col += 8;                                      //after write a char,Col point the next place
            ColCounter = 0;
        }
        LMR ++ ;
        Col = 0;
    }
}


void LCD19264_StringDisp_Anti(unsigned char Page,unsigned char Col,unsigned char *DispStr)
{
     unsigned char LMR;              // left /middle /right screen
    unsigned char DispCh = 0;
    unsigned char ColCounter;
    unsigned char ColTest;
    ColTest = Col;
    if(Page >= 8) return;
    if(Col >= 192) return;
    while(ColTest >= 8)
    {
        ColTest -= 8;
    }
    if(ColTest != 0) return;

    LMR = 1;
    while(Col >= 64)
    {
        Col -= 64;
        LMR ++;
    }

    ColCounter = 0;
    while(LMR < 4)
    {
        while(Col <= 56)
        {
            LCD19264_WriteCom(LMR,0xB8 + Page);           // Set the first Page of the char
            LCD19264_WriteCom(LMR,0x40 + Col);            // Set the start Col of the char

            DispCh = *(DispStr ++);                       //Read a char to display
            if( (DispCh >126) || (DispCh <32) ) return;   //test the char leagle or not

            for(unsigned char i=0;i<16;i++)               //Read the img of DispCh
            {
                LCD19264_DispBuffer[i] = ASCII_SongTi_8_16[DispCh-32][i];
            }

            while(ColCounter < 8)                         //Write the first page of the char
            {
                LCD19264_DataW( ~LCD19264_DispBuffer[ColCounter ++] );
            }
            LCD19264_WriteCom(LMR,0xB8 + Page + 1);       // Set the second Page of the char
            LCD19264_WriteCom(LMR,0x40 + Col);            // Set start Col of the char
            while(ColCounter < 16)                        //Write the first page of the char
            {
                LCD19264_DataW( ~LCD19264_DispBuffer[ColCounter ++] );
            }
            Col += 8;                                      //after write a char,Col point the next place
            ColCounter = 0;
        }
        LMR ++ ;
        Col = 0;
    }
}
void LCD19264_CN_Disp(unsigned char Page,unsigned char Col,const unsigned char *pCN)
{
    unsigned char LMR;              // left /middle /right screen
    unsigned char ColCounter;
    ColCounter = 0;
    if(Page > 6) return;
    if(Col > 176) return;
    LMR = 1;
    while(Col >= 64)
    {
        Col -= 64;
        LMR ++;
    }
    if(Col > 48) return;
    _FlashReadBytes((unsigned long )(pCN) ,32,LCD19264_DispBuffer );
    LCD19264_WriteCom(LMR,0xB8 + Page);           // Set the first Page of the char
    LCD19264_WriteCom(LMR,0x40 + Col);            // Set the start Col of the char
    while(ColCounter < 16)                         //Write the first page of the char
    {
       LCD19264_DataW( LCD19264_DispBuffer[ColCounter ++] );
    }
    LCD19264_WriteCom(LMR,0xB8 + Page + 1);       // Set the second Page of the char
    LCD19264_WriteCom(LMR,0x40 + Col);            // Set start Col of the char
    while(ColCounter < 32)                        //Write the first page of the char
    {
        LCD19264_DataW( LCD19264_DispBuffer[ColCounter ++] );
    }
}
void LCD19264_CN_Disp_Anti(unsigned char Page,unsigned char Col,const unsigned char *pCN)
{
    unsigned char LMR;              // left /middle /right screen
    unsigned char ColCounter;
    ColCounter = 0;
    if(Page > 6) return;
    if(Col > 176) return;
    LMR = 1;
    while(Col >= 64)
    {
        Col -= 64;
        LMR ++;
    }
    if(Col > 48) return;
    _FlashReadBytes((unsigned long )(pCN) ,32,LCD19264_DispBuffer );
    LCD19264_WriteCom(LMR,0xB8 + Page);           // Set the first Page of the char
    LCD19264_WriteCom(LMR,0x40 + Col);            // Set the start Col of the char
    while(ColCounter < 16)                         //Write the first page of the char
    {
       LCD19264_DataW( ~LCD19264_DispBuffer[ColCounter ++] );
    }
    LCD19264_WriteCom(LMR,0xB8 + Page + 1);       // Set the second Page of the char
    LCD19264_WriteCom(LMR,0x40 + Col);            // Set start Col of the char
    while(ColCounter < 32)                        //Write the first page of the char
    {
        LCD19264_DataW( ~LCD19264_DispBuffer[ColCounter ++] );
    }
}


void LCD19264_LineDisp(unsigned char Page ,unsigned char Col,unsigned char Wide,const unsigned char *pImg)
{
    unsigned char StartLMR ,RecLMR;
    unsigned char ColRel;
    unsigned char WideUnprinted;
    unsigned char FlashReadAmount;
    unsigned char FlashReadOffset;
    unsigned char BufferIndex;

    StartLMR = 1;
    ColRel = Col;
    while(ColRel > 63)
    {
        ColRel -= 64;
        StartLMR ++;
    }

    RecLMR = StartLMR;
    WideUnprinted = Wide;
    FlashReadOffset = 0;
    BufferIndex = 64;
    /************************************Wriet Data****************************/
        while(RecLMR < 4)                                //Screen is not over
        {
            LCD19264_WriteCom(RecLMR,0xB8 + Page);       //Set Page
            LCD19264_WriteCom(RecLMR,0x40 + ColRel);     //Set Start Col

            while((ColRel++ < 64))
            {
                if(BufferIndex >63)                      //Data in Buffer is displayed over
                {                                        //Read Data from flash
                    if(WideUnprinted > 64)
                    {
                        FlashReadAmount = 64;
                    }
                    else
                    {
                        FlashReadAmount = WideUnprinted;
                    }
                    _FlashReadBytes((unsigned long )(pImg) + FlashReadOffset,FlashReadAmount,LCD19264_DispBuffer );
                    BufferIndex = 0;                    //
                    FlashReadOffset += 64;              //Image Offset
                }
                LCD19264_DataW(LCD19264_DispBuffer[BufferIndex ++]);
                if((--WideUnprinted) == 0 ) return;
            }
            RecLMR ++;
            ColRel = 0;
        }
    /*************************************************************************/
}
void LCD19264_LineDisp_Anti(unsigned char Page ,unsigned char Col,unsigned char Wide,const unsigned char *pImg)
{
    unsigned char StartLMR ,RecLMR;
    unsigned char ColRel;
    unsigned char WideUnprinted;
    unsigned char FlashReadAmount;
    unsigned char FlashReadOffset;
    unsigned char BufferIndex;

    StartLMR = 1;
    ColRel = Col;
    while(ColRel > 63)
    {
        ColRel -= 64;
        StartLMR ++;
    }

    RecLMR = StartLMR;
    WideUnprinted = Wide;
    FlashReadOffset = 0;
    BufferIndex = 64;
    /************************************Wriet Data****************************/
        while(RecLMR < 4)
        {
            LCD19264_WriteCom(RecLMR,0xB8 + Page);
            LCD19264_WriteCom(RecLMR,0x40 + ColRel);

            while((ColRel++ < 64))
            {
                if(BufferIndex >63)
                {
                    if(WideUnprinted > 64)
                    {
                        FlashReadAmount = 64;
                    }
                    else
                    {
                        FlashReadAmount = WideUnprinted;
                    }
                    _FlashReadBytes((unsigned long )(pImg) + FlashReadOffset,FlashReadAmount,LCD19264_DispBuffer );
                    BufferIndex = 0;
                    FlashReadOffset += 64;
                }
                LCD19264_DataW(~LCD19264_DispBuffer[BufferIndex ++]);
                if((--WideUnprinted) == 0 ) return;
            }
            RecLMR ++;
            ColRel = 0;
        }
    /*************************************************************************/
}
/****************************************************************************
 * The High must be a multiple of 8.
 ****************************************************************************/
void LCD19264_ImgDisp(unsigned char StartPage ,unsigned char StartCol ,\
unsigned char Wide ,unsigned char PageHigh ,const unsigned char *pImg)
{
    while( (PageHigh > 0 ) && (StartPage < 8) )
    {
        LCD19264_LineDisp(StartPage,StartCol,Wide,pImg);
        pImg += Wide;
        PageHigh --;
        StartPage ++;
    }
}
void LCD19264_ImgDisp_Anti(unsigned char StartPage ,unsigned char StartCol ,\
unsigned char Wide ,unsigned char PageHigh ,const unsigned char *pImg)
{
    while( (PageHigh > 0 ) && (StartPage < 8) )
    {
        LCD19264_LineDisp_Anti(StartPage,StartCol,Wide,pImg);
        pImg += Wide;
        PageHigh --;
        StartPage ++;
    }
}